package com.blogspot.wanyancan.client.image;

import com.blogspot.wanyancan.client.image.DynaTableDataProvider.RowDataAcceptor;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Widget;

public class DynaTableWidget extends Composite {

	private class NavBar extends Composite implements ClickListener {

		public NavBar() {
			initWidget(bar);
			bar.setStyleName("navbar");
			status.setStyleName("status");

			HorizontalPanel buttons = new HorizontalPanel();
			buttons.add(gotoFirst);
			buttons.add(gotoPrev);
			buttons.add(gotoNext);
			bar.add(buttons, DockPanel.EAST);
			bar.setCellHorizontalAlignment(buttons, DockPanel.ALIGN_RIGHT);
			bar.add(status, DockPanel.CENTER);
			bar.setVerticalAlignment(DockPanel.ALIGN_MIDDLE);
			bar.setCellHorizontalAlignment(status, HasAlignment.ALIGN_RIGHT);
			bar.setCellVerticalAlignment(status, HasAlignment.ALIGN_MIDDLE);
			bar.setCellWidth(status, "100%");

			// Initialize prev & first button to disabled.
			//
			gotoPrev.setEnabled(false);
			gotoFirst.setEnabled(false);
		}

		public void onClick(Widget sender) {
			if (sender == gotoNext) {
				startRow += grid.getRowCount();
				refresh();
			} else if (sender == gotoPrev) {
				startRow -= grid.getRowCount();
				if (startRow < 0) {
					startRow = 0;
				}
				refresh();
			} else if (sender == gotoFirst) {
				startRow = 0;
				refresh();
			}
		}

		public final DockPanel bar = new DockPanel();

		public final Button gotoFirst = new Button("|&lt;&lt;", this);

		public final Button gotoNext = new Button("&gt;", this);

		public final Button gotoPrev = new Button("&lt;", this);

		public final HTML status = new HTML();
	}

	private class RowDataAcceptorImpl implements RowDataAcceptor {
		public void accept(int startRow, ImageRec[] imgs) {
			int i = 0;
			for(;i<imgs.length; i++){
				cellpanels[i].UpdateCell(imgs[i]);
				cellpanels[i].setVisible(true);
			}
			for(;i<grid.getRowCount(); i++){
				cellpanels[i].setVisible(false);
			}
			// Synchronize the nav buttons.
			//
			navbar.gotoNext.setEnabled(true);
			navbar.gotoFirst.setEnabled(startRow > 0);
			navbar.gotoPrev.setEnabled(startRow > 0);

			// Update the status message.
			//
			setStatusText((startRow) + " - " + (startRow + imgs.length));
		}
		public void accept__backup(int startRow, String[][] data) {

			int destRowCount = grid.getRowCount();
			int destColCount = grid.getCellCount(0);
			assert (data.length <= destRowCount) : "Too many rows";

			int srcRowIndex = 0;
			int srcRowCount = data.length;
			int destRowIndex = 1; // skip table head row
			for (; srcRowIndex < srcRowCount; ++srcRowIndex, ++destRowIndex) {
				String[] srcRowData = data[srcRowIndex];
				assert (srcRowData.length == destColCount) : " Column count mismatch";
				for (int srcColIndex = 0; srcColIndex < destColCount; ++srcColIndex) {
					String cellHTML = srcRowData[srcColIndex];
					grid.setText(destRowIndex, srcColIndex, cellHTML);
				}
			}

			// Clear remaining table rows.
			//
			boolean isLastPage = false;
			for (; destRowIndex < destRowCount + 1; ++destRowIndex) {
				isLastPage = true;
				for (int destColIndex = 0; destColIndex < destColCount; ++destColIndex) {
					grid.clearCell(destRowIndex, destColIndex);
				}
			}

			// Synchronize the nav buttons.
			//
			navbar.gotoNext.setEnabled(!isLastPage);
			navbar.gotoFirst.setEnabled(startRow > 0);
			navbar.gotoPrev.setEnabled(startRow > 0);

			// Update the status message.
			//
			setStatusText((startRow + 1) + " - " + (startRow + srcRowCount));
		}

		public void failed(Throwable caught) {
			String msg = "Failed to access data";
			if (caught != null) {
				msg += ": " + caught.getMessage();
			}
			setStatusText(msg);
		}
	}

	public DynaTableWidget(DynaTableDataProvider provider, int rowCount) {
		this.provider = provider;
		initTable(rowCount);
		grid.setStyleName("table");
		outer.add(navbar, DockPanel.NORTH);
		outer.add(grid, DockPanel.CENTER);

		initWidget(outer);
		setStyleName("DynaTable-DynaTableWidget");
	}

	private void initTable(int rowCount) {
		grid.resize(rowCount, 1);
		grid.setBorderWidth(1);
		cellpanels = new CellPanel[rowCount];
		for (int i = 0; i < rowCount; i++) {
			cellpanels[i] = new CellPanel(provider, this);
			cellpanels[i].setWidth("100%");
			grid.setWidget(i, 0, cellpanels[i]);
		}
	}

	public void setStatusText(String text) {
		navbar.status.setText(text);
	}

	public void clearStatusText() {
		navbar.status.setHTML("&nbsp;");
	}

	public void refresh() {
		// Disable buttons temporarily to stop the user from running off the
		// end.
		//
		navbar.gotoFirst.setEnabled(false);
		navbar.gotoPrev.setEnabled(false);
		navbar.gotoNext.setEnabled(false);

		setStatusText("Please wait...");
		provider.updateRowData(startRow, grid.getRowCount(), acceptor);
	}

	private final RowDataAcceptor acceptor = new RowDataAcceptorImpl();

	private final NavBar navbar = new NavBar();

	private final DockPanel outer = new DockPanel();

	private final DynaTableDataProvider provider;

	private int startRow = 0;

	private CellPanel[] cellpanels;
	private final Grid grid = new Grid();
}
